package com.valsong.sandbox.mock.filter;

import com.alibaba.jvm.sandbox.api.listener.ext.Advice;
import com.valsong.sandbox.mock.Invoker;
import com.valsong.sandbox.mock.MockConfig;
import com.valsong.sandbox.mock.MockFilter;
import lombok.extern.slf4j.Slf4j;

import javax.inject.Inject;
import javax.inject.Named;
import java.lang.reflect.AccessibleObject;
import java.util.Optional;

import static com.valsong.sandbox.mock.constant.MockConstants.SHOULD_MOCK_METHOD;

@Slf4j
public class FacadeMockFilter implements MockFilter {

    @Inject
    @Named("groovyFileInvoker")
    private Invoker groovyFileInvoker;

    @Override
    public boolean shouldMock(Advice advice, MockConfig MockConfig) {
        return  doShouldMock(advice, MockConfig);
    }

    private boolean doShouldMock(Advice advice, MockConfig MockConfig) {
        String mockFilterPath = MockConfig.getMockFilter();

        if (mockFilterPath != null && !(mockFilterPath = mockFilterPath.trim()).isEmpty()) {
            Boolean shouldMock = (Boolean) groovyFileInvoker.invoke(mockFilterPath, SHOULD_MOCK_METHOD, advice);
            if (log.isDebugEnabled()) {
                String classPattern = MockConfig.getClassPattern();
                AccessibleObject method = advice.getBehavior().getTarget();
                log.debug("classPattern:[{}] method:[{}] shouldMock:[{}] mockerFilter:[{}]", classPattern, method, shouldMock, mockFilterPath);
            }
            return Optional.ofNullable(shouldMock).orElse(false);
        }
        return true;
    }
}
